#!/usr/bin/env bash

#先将以前启动的容器全部down
docker-compose down

set -e

install_yq() {
  echo "检测到未安装 yq，开始安装..."
  wget -q https://github.com/mikefarah/yq/releases/download/v4.16.2/yq_linux_amd64 -O /usr/local/bin/yq
  chmod +x /usr/local/bin/yq
  echo "yq 安装完成。"
}

check_yq_version() {
  yq_version=$(yq --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')

  version_compare() {
    IFS='.' read -r -a v1 <<< "$1"
    IFS='.' read -r -a v2 <<< "$2"
    for i in 0 1 2; do
      [[ -z "${v1[i]}" ]] && v1[i]=0
      [[ -z "${v2[i]}" ]] && v2[i]=0
      if ((10#${v1[i]} > 10#${v2[i]})); then
        return 0
      elif ((10#${v1[i]} < 10#${v2[i]})); then
        return 1
      fi
    done
    return 0
  }

  if ! version_compare "$yq_version" "4.0.0"; then
    echo "检测到 yq 版本低于 4.0.0，开始重新安装..."
    install_yq
  else
    echo "检测到 yq 版本满足要求: $yq_version"
  fi
}

# 检查是否安装 yq
if ! command -v yq &>/dev/null; then
  install_yq
else
  check_yq_version
fi




# 加载 .env 并导出
set -o allexport
if [ -f ".env" ]; then
  source .env
else
  echo ".env 文件不存在！"
  exit 1
fi
set +o allexport

# 遍历所有 *.template 文件
find . -type f -name "*.template" | while read -r template_file; do
  target_file="${template_file%.template}"
  echo "生成: $target_file"

  cp "$template_file" "$target_file"

  for var in $(env | grep -o '^[^=]*'); do
    value=$(printenv "$var")
    sed -i "s|\${$var}|$value|g" "$target_file"
  done
done

echo "✅ 全部替换完成(.template文件 注入值完成)。"

COMPOSE_FILE="docker-compose.yml"

if [ ! -f "$COMPOSE_FILE" ]; then
  echo "$COMPOSE_FILE 不存在"
  exit 1
fi

if [ ! -f ".env" ]; then
  echo ".env 文件不存在"
  exit 1
fi

export $(grep -v '^#' .env | xargs)

if [ -z "$REQUIRE_SERVICES" ]; then
  echo "未定义 REQUIRE_SERVICES，全部保留"
  exit 0
fi

ALL_SERVICES=$(yq eval '.services | keys | .[]' "$COMPOSE_FILE" | tr '[:upper:]' '[:lower:]')

IFS=',' read -ra KEEP_SERVICES_RAW <<< "$REQUIRE_SERVICES"
KEEP_SERVICES=()

DEFAULT_KEEP=("backend" "frontend")

for svc in "${KEEP_SERVICES_RAW[@]}"; do
  svc=$(echo "$svc" | tr '[:upper:]' '[:lower:]' | xargs)
  KEEP_SERVICES+=("$svc")
done

for dsvc in "${DEFAULT_KEEP[@]}"; do
  skip=0
  for ksvc in "${KEEP_SERVICES[@]}"; do
    if [[ "$ksvc" == "$dsvc" ]]; then
      skip=1
      break
    fi
  done
  if [[ $skip -eq 0 ]]; then
    KEEP_SERVICES+=("$dsvc")
  fi
done

echo "需要保留的服务(包含默认): ${KEEP_SERVICES[*]}"

DELETE_SERVICES=()
for svc in $ALL_SERVICES; do
  keep=0
  for ksvc in "${KEEP_SERVICES[@]}"; do
    if [[ "$svc" == "$ksvc" ]]; then
      keep=1
      break
    fi
  done
  if [[ $keep -eq 0 ]]; then
    DELETE_SERVICES+=("$svc")
  fi
done

echo "需要移除的服务: ${DELETE_SERVICES[*]}"

# 先移除 services 中被删除的服务
YQ_DEL=""
for svc in "${DELETE_SERVICES[@]}"; do
  echo "正在移除服务: $svc"
  YQ_DEL="$YQ_DEL | del(.services.$svc)"
done

# 再处理 depends_on，移除保留服务中 depends_on 对已被删除服务的引用
for svc in "${KEEP_SERVICES[@]}"; do
  # 生成jq条件过滤字符串，比如: select(. == "redis" or . == "mysql")
  filter_cond=$(printf 'select(. == "%s") or ' "${DELETE_SERVICES[@]}")
  filter_cond=${filter_cond% or }

  # 先检测这个服务有没有 depends_on
  has_depends=$(yq eval ".services.$svc.depends_on" "$COMPOSE_FILE" 2>/dev/null || echo "null")

  if [[ "$has_depends" != "null" && "$has_depends" != "[]" ]]; then
    echo "清理服务 $svc 的 depends_on 中已被移除的依赖"

    # 删除 depends_on 中的已被移除服务
    # 注意 yq 对数组过滤写法:
    YQ_DEL="$YQ_DEL | (.services.$svc.depends_on |= map(select(. != null) | select(. != null) | select( ( . == \"\" ) or ( . != null ) )) )"
    # 上面写法为了保证安全，下面改用 filter 删除 DELETE_SERVICES 中的元素
    for rem_svc in "${DELETE_SERVICES[@]}"; do
      # 替换YQ_DEL，追加过滤删除已删除的依赖项
      YQ_DEL="$YQ_DEL | (.services.$svc.depends_on |= map(select(. != \"$rem_svc\")))"
    done
  fi
done

YQ_DEL=${YQ_DEL# | }

# 使用 yq 覆盖原文件
yq eval "$YQ_DEL" -i "$COMPOSE_FILE"

echo "✅ 已直接更新(动态container): $COMPOSE_FILE"

docker-compose build --no-cache
docker-compose up -d